//
//  YTImageCell.swift
//  YTImgeViewer
//
//  Created by aron on 2018/5/24.
//

import UIKit
import Kingfisher

class YTImageCell: UICollectionViewCell, YTImgeContainerProtocol, UIScrollViewDelegate {

    // 处理图片加载进度的插入点，是一个代理，会把进度显示需要用到的信息提交给代理，代理去处理进度显示的View
    weak var progressHandlerObj: YTImgeLoadProgressProtocol? {
        didSet {
            // 向插件模块发送消息
            progressHandlerObj?.containerView(self, containerView: self, setupUI: true)
        }
    }
    
    // 处理Cell事件的回调
    weak var cellDelegate: YTImageCellProtocol?
    
    // 绑定的图片加载进度的View，会在progressHandlerObj中进行getter/setter操作
    private var _progressView: UIView?
    
    var image: YTImage? {
        didSet {
            self.loadImage(image: image)
        }
    }
    
    private lazy var scrollView: UIScrollView = {
        let scrollView = UIScrollView()
        // 设置缩放的比例
        scrollView.maximumZoomScale = 2
        scrollView.isMultipleTouchEnabled = true
        scrollView.showsVerticalScrollIndicator = false
        scrollView.showsHorizontalScrollIndicator = false
        scrollView.zoomScale = 3
        scrollView.delegate = self
        scrollView.clipsToBounds = true
        return scrollView
    }()
    
    lazy var imageView: UIImageView = {
        let imageView = UIImageView()
        imageView.contentMode = .scaleAspectFit
        imageView.clipsToBounds = true
        return imageView
    }()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        setupUI()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        
        setupFrame()
    }
    
    // MARK:- setup
    
    func setupUI() {
        self.contentView.addSubview(self.scrollView)
        self.scrollView.addSubview(self.imageView)
        
        // 添加双击手势，用于处理缩放
        let doubleTapGes = UITapGestureRecognizer(target: self, action: #selector(doubleTap(gesture:)))
        doubleTapGes.numberOfTapsRequired = 2
        self.contentView.addGestureRecognizer(doubleTapGes)
        
        // 添加点击手势
        let singleTap = UITapGestureRecognizer(target: self, action: #selector(singleTap(gesture:)))
        singleTap.numberOfTapsRequired = 1
        singleTap.require(toFail: doubleTapGes)
        self.contentView.addGestureRecognizer(singleTap)
        
        // 向插件模块发送消息
        progressHandlerObj?.containerView(self, containerView: self, setupUI: true)
        
    }
    
    func setupFrame() {
        self.scrollView.frame = self.bounds
        self.scrollView.setZoomScale(1.0, animated: false)
        self.imageView.frame = calculateFitImageFrame()
        self.scrollView.setZoomScale(1.0, animated: false)
        // 向插件模块发送消息
        progressHandlerObj?.containerView(self, containerView: self, layoutSubviews: true)
    }
    
    // 计算合适的图片Frame
    func calculateFitImageFrame() -> CGRect {
        
        // 按比例处理图片合适的显示尺寸
        var fitImageSize = CGSize.zero
        if let image = imageView.image {
            let width = scrollView.bounds.width
            let scale = image.size.height / image.size.width
            fitImageSize = CGSize(width: width, height: scale * width)
        }
        
        // 处理图片的位置
        let y = (scrollView.bounds.height - fitImageSize.height) > 0 ? (scrollView.bounds.height - fitImageSize.height) * 0.5 : 0
        return CGRect(x: 0, y: y, width: fitImageSize.width, height: fitImageSize.height)
    }
    
    func loadImage(image: YTImage?) {
        guard let image = image else {
            return
        }
        var imageUrlString: String = ""
        if image.highUrlString != nil {
            imageUrlString = image.highUrlString!
        } else if image.thumbUrlString != nil {
            imageUrlString = image.thumbUrlString!
        }
        
        // 向插件模块发送消息
        progressHandlerObj?.containerView(self, containerView: self, startLoadImage: true)
        self.imageView.kf.setImage(with: URL(string: imageUrlString), placeholder: image.placeholderImage, options: nil, progressBlock: { (receivedSize: Int64, totalSize: Int64) in
            // 向插件模块发送消息
            self.progressHandlerObj?.containerView(self, containerView: self, loadingImageWithReceivedSize: receivedSize, totalSize: totalSize)
        }) { (image: Image?, error: NSError?, cacheType: CacheType, imageURL: URL?) in
            // 向插件模块发送消息
            self.progressHandlerObj?.containerView(self, containerView: self, completeLoadImage: true)
            self.setupFrame()
        }
    }
    
    
    // MARK:- Gesture Handler
    
    @objc func doubleTap(gesture: UITapGestureRecognizer) {
        let tapPoint = gesture.location(in: self.contentView)
        if (scrollView.zoomScale - 1.0) <= 0.01 {
            // 放大2倍
            // 放大两倍的区域是以点击位置为中心，宽度和高度为scrollView一半的区域
            let zoomW = scrollView.bounds.width / 2
            let zoomH = scrollView.bounds.height / 2
            let zoomX = tapPoint.x - zoomW / 2
            let zoomY = tapPoint.y - zoomH / 2
            let zoomFrame = CGRect(x: zoomX, y: zoomY, width: zoomW, height: zoomH)
            scrollView.zoom(to: zoomFrame, animated: true)
        } else {
            // 缩小为1倍
            scrollView.setZoomScale(1, animated: true)
        }
    }
    
    @objc func singleTap(gesture: UITapGestureRecognizer) {
        self.cellDelegate?.imageCell(self, didSingleTap: true)
    }
    
    // MARK:- UIScrollViewDelegate
    func viewForZooming(in scrollView: UIScrollView) -> UIView? {
        return self.imageView
    }
    
     func scrollViewDidZoom(_ scrollView: UIScrollView) {
        // 设置图片的中心点为ContentSize的中心店，图片才不会跑偏了
        self.imageView.center = self.centerOfContentSize()
    }
    
    /// 计算contentSize应处于的中心位置，
    private func centerOfContentSize() -> CGPoint {
        let deltaWidth = bounds.width - scrollView.contentSize.width
        let offsetX = deltaWidth > 0 ? deltaWidth * 0.5 : 0
        let deltaHeight = bounds.height - scrollView.contentSize.height
        let offsetY = deltaHeight > 0 ? deltaHeight * 0.5 : 0
        let centerPoint = CGPoint(x: scrollView.contentSize.width * 0.5 + offsetX,
                y: scrollView.contentSize.height * 0.5 + offsetY)
        return centerPoint
    }
    
    // MARK:- YTImgeContainerProtocol
    func progressView() -> UIView? {
        return _progressView
    }
    
    func setProgressView(progressView: UIView) {
        _progressView = progressView
    }

}
